﻿/*
* This software is the confidential and proprietary
* information of NetBay
* Such confidential information should not be disclosed
* NetBay copyright(c) 2010
*/
#region Using

using System;
using System.Collections.Generic;
using System.Data.Common;
using NetBay.Core.BusinessEntities;
using NetBay.Core.Extensions;
using NetBay.Core.DataAccess;
using System.ComponentModel;
using System.Data;
using NetBay.Core.Log;

#endregion

namespace Rio.Doc.DataAccess 
{
    public class DA_FolderType
    {
        #region Enum
        /// <summary>
        /// List of DB functions to access data
        /// </summary>
        public enum DbFunction
        {
            [DescriptionAttribute("")]
            None,
            [DescriptionAttribute("P_FOLDER_TYPE_Get_ByOrgaId")]
            GetFolderTypeByOrganization,
            [DescriptionAttribute("P_FOLDER_TYPE_Get_ByGroupId")]
            GetFolderTypeByGroup,
            [DescriptionAttribute("P_FOLDER_TYPE_List")]
            GetAllFolderTypes,
            [DescriptionAttribute("P_FOLDER_TYPE_HasVersionning")]
            FolderTypeHasVersionning,
            [DescriptionAttribute("P_ADMIN_FOLDERTYPE_ADD")]
            AddFolderType,
            [DescriptionAttribute("P_ADMIN_FOLDERTYPE_DELETE")]
            DeactivateFolderType,
            [DescriptionAttribute("P_ADMIN_FOLDERTYPEGRPRGT_ADD")]
            AddGroupToFolderType,
            [DescriptionAttribute("P_ADMIN_FOLDERTYPEGRPRGT_DEL")]
            RemoveGroupsToFolderType,
            [DescriptionAttribute("P_ADMIN_FOLDERTYPEGRPRGT_UPD")]
            UpdateGroupToFolderType,
            [DescriptionAttribute("P_ADMIN_FolderType_Rank_Update")]
            UpdateFolderTypeRank,
            [DescriptionAttribute("P_ADMIN_FolderType_Upd")]
            UpdateFolderType,
            [DescriptionAttribute("P_ADMIN_FolderTypeGrpRgt_Get")]
            GetGroups,
            [DescriptionAttribute("P_FOLDER_TYPE_Get_ByUserId")]
            GetFolderTypeByUserId,
            [DescriptionAttribute("P_ADMIN_FolderTypeRgt_Get")]
            GetFolderTypeRightsByGroupId,
            [DescriptionAttribute("P_FOLDER_TYPE_Get_ById")]
            GetFolderTypeById,
            [DescriptionAttribute("P_ADMIN_FolderTypeRgt_Del")]
            RemoveGroupsToFolderTypeRights
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="p_lOrganizationId"></param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeByOrganization(long userId, long p_lOrganizationId)
        {
            var db = DbHelper.DataBase;

            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeByOrganization.szGetDescription());
            db.AddInParameter(dbCommand, "p_userId", DbType.Int64, userId);
            db.AddInParameter(dbCommand, "p_organizationId", DbType.Int64, p_lOrganizationId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Folders the type has versionning.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <returns></returns>
        public static bool FolderTypeHasVersionning(long folderTypeId)
        {
            var db = DbHelper.DataBase;

            var dbCommand = db.GetNewCommand(DbFunction.FolderTypeHasVersionning.szGetDescription());
            db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, folderTypeId);

            bool result = false;
            using (IDataReader reader = db.ExecuteReader(dbCommand))
            {
                while (reader.Read())
                {
                    result = reader.GetBooleanValue("RESULT");
                }
            }
            return result;
        }

        /// <summary>
        /// Gets the folder type by organization.
        /// </summary>
        /// <param name="p_lOrganizationId">The P_L organization id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeByOrganization(long p_lOrganizationId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetFolderTypeByOrganization.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeByOrganization.szGetDescription());
            db.AddInParameter(dbCommand, "p_organizationId", DbType.Int64, p_lOrganizationId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Gets the folder type by id.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeById(long folderTypeId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetFolderTypeById.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeById.szGetDescription());
            db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, folderTypeId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Gets the folder type by user id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeByUserId(long userId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetFolderTypeByUserId.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeByUserId.szGetDescription());
            db.AddInParameter(dbCommand, "p_lUserId", DbType.Int64, userId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Gets the folder type by organization.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeGroups(long folderTypeId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetGroups.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetGroups.szGetDescription());
            db.AddInParameter(dbCommand, "p_FolderTypeId", DbType.Int64, folderTypeId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Gets the folder type by organization.
        /// </summary>
        /// <param name="groupId">The group id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeRightsByGroupId(long groupId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetFolderTypeRightsByGroupId.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeRightsByGroupId.szGetDescription());
            db.AddInParameter(dbCommand, "p_lGroupId", DbType.Int64, groupId);
            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Deletes the type of the O folder.
        /// </summary>
        /// <param name="identifier">The identifier.</param>
        /// <returns></returns>
        public static StoredProcedureResult DeactivateFolderType(long identifier)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.DeactivateFolderType.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.DeactivateFolderType.szGetDescription());
            db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, identifier);
            return db.ExecuteAndGetResult(dbCommand);
        }

        /// <summary>
        /// Updates the folder type rank.
        /// </summary>
        /// <param name="sourceId">The source id.</param>
        /// <param name="sourceRank">The source rank.</param>
        /// <param name="destinationId">The destination id.</param>
        /// <param name="destinationRank">The destination rank.</param>
        /// <returns></returns>
        public static bool UpdateFolderTypeRank(long sourceId, int sourceRank, long destinationId, int destinationRank)
        {
            bool result = false;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.UpdateFolderTypeRank.szGetDescription());
            LogManager.Instance().LogDebug("(p_lOrgaSource<" + sourceId + "> p_lOrgaSourceRank<" + sourceRank + "> p_lOrgaDestination<" + destinationId + "> p_lOrgaDestinationRank<" + destinationRank + ">)...");

            try
            {
                var db = DbHelper.DataBase;

                using (var dbCommand = db.GetNewCommand(DbFunction.UpdateFolderTypeRank.szGetDescription()))
                {
                    db.AddInParameter(dbCommand, "p_lFolderTypeSource", DbType.Int64, sourceId);
                    db.AddInParameter(dbCommand, "p_lFolderTypeSourceRank", DbType.Int32, sourceRank);
                    db.AddInParameter(dbCommand, "p_lFolderTypeDestination", DbType.Int64, destinationId);
                    db.AddInParameter(dbCommand, "p_lFolderTypeDestinationRank", DbType.Int32, destinationRank);
                    db.ExecuteNonQuery(dbCommand);
                }

                result = true;
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogError("UpdateFolderTypeRank Exception [" + ex.Message + "]");
            }

            return result;
        }

        /// <summary>
        /// Adds the type of the folder.
        /// </summary>
        /// <param name="organizationIdentifier">The organization identifier.</param>
        /// <param name="name">The name.</param>
        /// <param name="description">The descrition.</param>
        /// <param name="groups">The groups.</param>
        /// <param name="natures">The natures.</param>
        /// <returns></returns>
        public static StoredProcedureResult AddFolderType(long organizationIdentifier, string name, string description, List<Group> groups, List<long> natures)
        {
            var db = DbHelper.DataBase;
            DbTransaction transaction = null;
            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.AddFolderType.szGetDescription());

            using (DbConnection connection_db_b = db.CreateConnection())
            {
                try
                {
                    connection_db_b.Open();
                    transaction = connection_db_b.BeginTransaction();

                    //Add foldertype
                    var dbCommand = db.GetNewCommand(DbFunction.AddFolderType.szGetDescription());
                    db.AddInParameter(dbCommand, "p_lOrganizationId", DbType.Int64, organizationIdentifier);
                    db.AddInParameter(dbCommand, "p_sFolderTypeLibelle", DbType.String, name);
                    db.AddInParameter(dbCommand, "p_sFolderTypeDescription", DbType.String, description);
                    StoredProcedureResult result = db.ExecuteAndGetResult(dbCommand, transaction);
                    if (result.HasError)
                    {
                        transaction.Rollback();
                        return result;
                    }

                    if (result.NewIdentifier > 0)
                    {
                        //Add groups
                        foreach (Group group in groups)
                        {
                            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.AddGroupToFolderType.szGetDescription());
                            dbCommand = db.GetNewCommand(DbFunction.AddGroupToFolderType.szGetDescription());
                            db.AddInParameter(dbCommand, "p_lFldTypeId", DbType.Int64, result.NewIdentifier);
                            db.AddInParameter(dbCommand, "p_lGroupId", DbType.Int64, group.Identifier);
                            db.AddInParameter(dbCommand, "p_iAdmin", DbType.Int32, Convert.ToInt32(group.IsAdministrator));
                            db.AddInParameter(dbCommand, "p_iAcquire", DbType.Int32, Convert.ToInt32(group.CanScann));
                            db.AddInParameter(dbCommand, "p_iAcquireExtended", DbType.Int32, Convert.ToInt32(group.CanScanExtended));
                            db.AddInParameter(dbCommand, "p_iConsult", DbType.Int32, Convert.ToInt32(group.CanConsult));
                            db.AddInParameter(dbCommand, "p_iConsultExtended", DbType.Int32, Convert.ToInt32(group.CanConsultExtended));
                            db.AddInParameter(dbCommand, "p_iUpdate", DbType.Int32, Convert.ToInt32(group.CanReorganize));
                            db.AddInParameter(dbCommand, "p_iRemove", DbType.Int32, Convert.ToInt32(group.CanDelete));
                            db.AddInParameter(dbCommand, "p_iTrash", DbType.Int32, Convert.ToInt32(group.CanTrash));
                            db.AddInParameter(dbCommand, "p_iSendmail", DbType.Int32, Convert.ToInt32(group.CanSendEmail));
                            db.AddInParameter(dbCommand, "p_iPrint", DbType.Int32, Convert.ToInt32(group.CanPrint));
                            db.AddInParameter(dbCommand, "p_iDownload", DbType.Int32, Convert.ToInt32(group.CanDownload));
                            db.AddInParameter(dbCommand, "p_iAnnotate", DbType.Int32, Convert.ToInt32(group.CanAnnotate));

                            StoredProcedureResult groupResult = db.ExecuteAndGetResult(dbCommand, transaction);
                            if (groupResult.HasError)
                            {
                                transaction.Rollback();
                                return result;
                            }
                        }

                        ////Add natures
                        //foreach (Group nature in natures)
                        //{
                        //}

                        transaction.Commit();
                        dbCommand.Dispose();
                    }

                }
                catch (Exception ex)
                {
                    LogManager.Instance().LogError("Exception -> " + Environment.NewLine + ex.Message);
                    if (transaction != null)
                    {
                        transaction.Rollback();
                        LogManager.Instance().LogInfo("Rollback() executed...");
                    }
                    return new StoredProcedureResult(ResultCode.Error, ex.Message);
                }

                return new StoredProcedureResult(ResultCode.Executed);
            }
        }

        /// <summary>
        /// Updates the type of the folder.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="organizationIdentifier">The organization identifier.</param>
        /// <param name="name">The name.</param>
        /// <param name="description">The descrition.</param>
        /// <param name="groups">The groups.</param>
        /// <param name="natures">The natures.</param>
        /// <returns></returns>
        public static StoredProcedureResult UpdateFolderType(long folderTypeId, long organizationIdentifier, string name, string description, List<Group> groups, List<long> natures)
        {
            var db = DbHelper.DataBase;
            DbTransaction transaction = null;
            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.UpdateFolderType.szGetDescription());

            using (DbConnection connection_db_b = db.CreateConnection())
            {
                try
                {
                    connection_db_b.Open();
                    transaction = connection_db_b.BeginTransaction();

                    //Update foldertype
                    var dbCommand = db.GetNewCommand(DbFunction.UpdateFolderType.szGetDescription());
                    db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, folderTypeId);
                    db.AddInParameter(dbCommand, "p_lOrganizationId", DbType.Int64, organizationIdentifier);
                    db.AddInParameter(dbCommand, "p_sFolderTypeLibelle", DbType.String, name);
                    db.AddInParameter(dbCommand, "p_sFolderTypeDescription", DbType.String, description);
                    StoredProcedureResult result = db.ExecuteAndGetResult(dbCommand, transaction);
                    if (result.HasError)
                    {
                        transaction.Rollback();
                        return result;
                    }

                    //Remove all groups 
                    dbCommand = db.GetNewCommand(DbFunction.RemoveGroupsToFolderType.szGetDescription());
                    db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, folderTypeId);
                    result = db.ExecuteAndGetResult(dbCommand, transaction);
                    if (result.HasError)
                    {
                        transaction.Rollback();
                        return result;
                    }

                    //Add groups
                    foreach (Group group in groups)
                    {
                        LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.AddGroupToFolderType.szGetDescription());
                        dbCommand = db.GetNewCommand(DbFunction.AddGroupToFolderType.szGetDescription());
                        db.AddInParameter(dbCommand, "p_lFldTypeId", DbType.Int64, folderTypeId);
                        db.AddInParameter(dbCommand, "p_lGroupId", DbType.Int64, group.Identifier);
                        db.AddInParameter(dbCommand, "p_iAdmin", DbType.Int32, Convert.ToInt32(group.IsAdministrator));
                        db.AddInParameter(dbCommand, "p_iAcquire", DbType.Int32, Convert.ToInt32(group.CanScann));
                        db.AddInParameter(dbCommand, "p_iAcquireExtended", DbType.Int32, Convert.ToInt32(group.CanScanExtended));
                        db.AddInParameter(dbCommand, "p_iConsult", DbType.Int32, Convert.ToInt32(group.CanConsult));
                        db.AddInParameter(dbCommand, "p_iConsultExtended", DbType.Int32, Convert.ToInt32(group.CanConsultExtended));
                        db.AddInParameter(dbCommand, "p_iUpdate", DbType.Int32, Convert.ToInt32(group.CanReorganize));
                        db.AddInParameter(dbCommand, "p_iRemove", DbType.Int32, Convert.ToInt32(group.CanDelete));
                        db.AddInParameter(dbCommand, "p_iTrash", DbType.Int32, Convert.ToInt32(group.CanTrash));
                        db.AddInParameter(dbCommand, "p_iSendmail", DbType.Int32, Convert.ToInt32(group.CanSendEmail));
                        db.AddInParameter(dbCommand, "p_iPrint", DbType.Int32, Convert.ToInt32(group.CanPrint));
                        db.AddInParameter(dbCommand, "p_iDownload", DbType.Int32, Convert.ToInt32(group.CanDownload));
                        db.AddInParameter(dbCommand, "p_iAnnotate", DbType.Int32, Convert.ToInt32(group.CanAnnotate));

                        StoredProcedureResult groupResult = db.ExecuteAndGetResult(dbCommand, transaction);
                        if (groupResult.HasError)
                        {
                            transaction.Rollback();
                            return result;
                        }
                    }

                    ////Add natures
                    //foreach (Group nature in natures)
                    //{
                    //}

                    transaction.Commit();
                    dbCommand.Dispose();

                }
                catch (Exception ex)
                {
                    LogManager.Instance().LogError("Exception -> " + Environment.NewLine + ex.Message);
                    if (transaction != null)
                    {
                        transaction.Rollback();
                        LogManager.Instance().LogInfo("Rollback() executed...");
                    }
                    return new StoredProcedureResult(ResultCode.Error, ex.Message);
                }

                return new StoredProcedureResult(ResultCode.Executed);
            }
        }

        /// <summary>
        /// Gets the folder type right by group.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="p_lGroupId">The P_L group id.</param>
        /// <returns></returns>
        public static IDataReader GetFolderTypeRightByGroup(long userId, long p_lGroupId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetFolderTypeByGroup.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetFolderTypeByGroup.szGetDescription());
            db.AddInParameter(dbCommand, "p_userId", DbType.Int64, userId);
            db.AddInParameter(dbCommand, "p_groupId", DbType.Int64, p_lGroupId);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Gets the type of all folder.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        public static IDataReader GetAllFolderType(long userId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.GetAllFolderTypes.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.GetAllFolderTypes.szGetDescription());
            db.AddInParameter(dbCommand, "p_lUserId", DbType.Int64, userId);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Folders the type has versioning.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <returns></returns>
        public static bool FolderTypeHasVersioning(long folderTypeId)
        {
            var db = DbHelper.DataBase;

            LogManager.Instance().LogDebugFormat("Calling SP: '{0}'", DbFunction.FolderTypeHasVersionning.szGetDescription());
            var dbCommand = db.GetNewCommand(DbFunction.FolderTypeHasVersionning.szGetDescription());
            db.AddInParameter(dbCommand, "p_lFolderTypeId", DbType.Int64, folderTypeId);

            bool result = false;
            using (IDataReader reader = db.ExecuteReader(dbCommand))
            {
                while (reader.Read())
                {
                    result = reader.GetBooleanValue("RESULT");
                }
            }
            return result;
        }
    }
}